<template>
  <n-card
      class="h-full"
      :content-style="{ padding: '5px' }"
      :header-style="{ padding: '5px' }"
      :segmented="true"
  >
    <template #header>
      <div class="flex items-center">
        <n-input class="mr-2" v-model:value="pattern" placeholder="搜索" size="small" />
        <n-button type="primary" size="small" @click="onAddGoal">添加</n-button>
        <n-switch size="small" v-model:value="expandAllFlag" />
      </div>
    </template>
    <n-tree
        :expanded-keys="getExpandedKeys"
        block-line
        :pattern="pattern"
        :data="departmentData"
        :node-props="nodeProps"
        selectable
        draggable
        @drop="handleDrop"
        :allow-drop="()=>true"
        :on-update:expanded-keys="onUpdateExpandedKeys"
    />
    <ModalDialog ref="modalDialogRef" @confirm="onDataFormConfirm" contentHeight="40vh">
      <template #content>
        <DataForm ref="dataFormRef" :options="formItems" :form-config="formConfig"/>
      </template>
    </ModalDialog>
    <n-dropdown
        placement="bottom-start"
        trigger="manual"
        :x="xRef"
        :y="yRef"
        :options="options"
        :show="showDropdownRef"
        :on-clickoutside="onClickoutside"
        @select="handleSelect"
    />
  </n-card>

</template>

<script lang="ts" setup>
import {post, Response} from '@/api/http'
import {
  addFields,
  addGoal,
  addLifeModeItems, changeFieldsTree, changeGoalsList,
  changeGoalState, deleteFields,
  deleteGoal, getFieldExpandKeys, getFieldsTree,
  getGoalsList,
  getTableList, saveFieldExpandKeys,
  startLifeMode
} from '@/api/url'
import {DataTableColumn, FormProps, NAvatar, useDialog, useMessage, NSlider, NInput, NTime, TreeOption} from 'naive-ui'
import {defineComponent, h, nextTick, onMounted, reactive, ref, shallowReactive, watch} from 'vue'
import useUserStore from "@/store/modules/user";
import { DataFormType, ModalDialogType, FormItem } from '@/types/components'
import UseSurfaceSettingStore from "@/store/modules/surfaceSetting";
import {renderTag, renderTimePicker} from "@/hooks/form";
import {TableActionModel, usePagination, useRenderAction, useRowKey, useTable, useTableColumn} from "@/hooks/table";
import { NIcon, NTree, TreeDropInfo, NButton } from "naive-ui";
import {obj2Map, stringify} from "@/utils";
import {UseConstsStore} from "@/store/modules/consts";

const userStore = useUserStore()
const useConsts = UseConstsStore()
const useSurfaceSetting = UseSurfaceSettingStore()
const message = useMessage()
const naiveDialog = useDialog()

interface GoalData {
  id?:number
  name?:string
  stageIds?:Map<number,Array<number>>
  label?:string
  key?:number
  fatherId?:number
  children?:Array<GoalData>
  hasOnStage?:boolean
}



const pattern= ref('');
const key = ref(new Date().getTime());
const departmentData = ref<Array<{key:number,label:number|string,childern?:Array<object>}>>([])

// 获取数据
async function doRefresh() {
  try {
    // table.tableLoading.value = true;
    const data: Response = await post({
      url: getFieldsTree,
      token:userStore.getToken()
    });
    departmentData.value = data.data.data
    // console.log(departmentData)
  }catch(e) {
    message.error((e as Error).message)
  }finally {
    // table.tableLoading.value = false;
  }
}
onMounted(doRefresh)
watch(key,doRefresh)

// 添加表单
const formConfig = {
  labelWidth: 100,
  size: 'medium',
  labelAlign: 'right',
} as FormProps
const formItems = [
  {
    label: 'id',
    type: 'input',
    key: 'id',
    hidden:true,
    disabled:true,
    value: ref(null),
    render: (formItem) => {
      return h(NInput, {
        hidden:true,
        disabled:true,
        value: formItem.value.value,
        onUpdateValue: (val) => {
          formItem.value.value = val
        },
      })
    },
  },
  {
    label: '领域名',
    key: 'name',
    value: ref(null),
    validator: (formItem, message) => {
      if (!formItem.value.value) {
        message.error('请输入领域名')
        return false
      }
      return true
    },
    render: (formItem) => {
      return h(NInput, {
        value: formItem.value.value,
        onUpdateValue: (val) => {
          formItem.value.value = val
        },
        placeholder: '请输入领域名',
      })
    },
  }
] as FormItem[]
let toAddGoal = 0;
const modalDialogRef = ref<ModalDialogType | null>(null)
const dataFormRef = ref<DataFormType | null>(null)
async function onDataFormConfirm() {
  if (dataFormRef.value?.validator()) {
    modalDialogRef.value?.toggle()
    if(toAddGoal === 0){
      await addNewGoal({...dataFormRef.value.generatorParams(), fatherId:0})
    }else {
      await addNewGoal({...dataFormRef.value.generatorParams(), fatherId:chooseRow?.fatherId,stageIds:chooseRow?.stageIds})
    }
  }
}
const addNewGoal = async (params:any)=>{
  try {
    // table.tableLoading.value = true;
    const data: Response = await post({
      url: addFields,
      data: params,
      token:userStore.getToken()
    });
    // console.log(data)
    message.success(data.msg)
  }catch(e) {
    message.error((e as Error).message)
  }finally {
    key.value = new Date().getTime();
  }
}
// 操作
function onAddGoal() {
  toAddGoal = 0;
  modalDialogRef.value?.toggle()
  nextTick(() => {
    dataFormRef.value?.reset()
  })
}
function onUpdateGoal(item: any) {
  // console.log(item)
  toAddGoal = 1;
  modalDialogRef.value?.toggle()
  nextTick(() => {
    formItems.forEach((it) => {
      const key = it.key
      const propName = item[key]
      // console.log(item)
      if (propName) {
        it.value.value = propName
      }
    })
  })
}
function onDeleteGoal(params: GoalData|null) {
  toAddGoal = 2;
  naiveDialog.warning({
    title: '提示',
    content: '是否要删除？',
    positiveText: '删除',
    onPositiveClick:async () => {
      try {
        // table.tableLoading.value = true;
        const data: Response = await post({
          url: deleteFields,
          data: params,
          token:userStore.getToken()
        });
        // console.log(data)
        message.success(data.msg)
      }catch(e) {
        message.error((e as Error).message)
      }finally {
        key.value = new Date().getTime();
      }
    },
  })
}


// 下拉菜单
let chooseRow:GoalData|null = null;
const options = [
  {
    label: "查看阶段",
    key: "show",
  },
  {
    label: "编辑",
    key: "edit",
  },
  {
    label: () => h("span", { style: { color: "red" } }, "删除"),
    key: "delete",
  },
];
const showDropdownRef = ref(false);
const xRef = ref(0);
const yRef = ref(0);
const onClickoutside = () => showDropdownRef.value = false;
const handleSelect = (key: string, node: string) => {
  // console.log(key, node);
  showDropdownRef.value = false;
  const str = key==='start'?'开启':key==='stop'?'暂停':'结束';
  if(key == "show"){
    if(chooseRow?.id)
      useSurfaceSetting.addIdToArray(chooseRow.id,useSurfaceSetting.getSurfaceSetting().showFieldId)
    //console.log(useSurfaceSetting.getSurfaceSetting().showGoalId)
  }
  if (key == "edit") {
    onUpdateGoal(chooseRow)
  }
  if (key == "delete") {
    onDeleteGoal(chooseRow)
  }
};
const nodeProps = ({ option }: { option: TreeOption }) => {
  // @contextmenu.prevent.stop="click2FieldSetting"
  //   @click="click2Field"
  return {
    // 左击
    onClick() {
      // onClick(e)
      if (!option.children && !option.disabled) {
        // message.info('[Click] ' + option.label)
        // console.log("onClick");
      }
    },
    // 双击
    ondblclick(e: MouseEvent) {
      if (option.key !== undefined) {
        // editSettings.toDealRowId = parseInt(option.key.toString());
        showDropdownRef.value = true;
        xRef.value = e.clientX;
        yRef.value = e.clientY;
        chooseRow = {...option} as GoalData;
        // deleteIdHasChild = option.children?.length > 0;
      }
    },
    // 右击
    onContextmenu(e: MouseEvent) {
      //取消默认的浏览器自带右键
      e.preventDefault();
      if (option.key !== undefined) {
        // editSettings.toDealRowId = parseInt(option.key.toString());
        showDropdownRef.value = true;
        xRef.value = e.clientX;
        yRef.value = e.clientY;
        chooseRow = {...option} as GoalData;
        // deleteIdHasChild = option.children?.length > 0;
      }
    },
  };
};

// 移动
function findSiblingsAndIndex(node: TreeOption, nodes?: any[]): [TreeOption[], number] | [null, null] {
  if (!nodes) return [null, null];
  for (let i = 0; i < nodes.length; ++i) {
    const siblingNode = nodes[i];
    if (siblingNode.key === node.key) return [nodes, i];
    const [siblings, index] = findSiblingsAndIndex(node, siblingNode.children);
    if (siblings && index !== null) return [siblings, index];
  }
  return [null, null];
}
const getOrignalData = (arg: Array<any>) => {
  const result: Array<any> = [];
  if(arg)  for (var i = 0; i < arg.length; i++) {
      const id = arg[i].key;
      const children1 = getOrignalData(arg[i].children);
      result.push({ id: id, subIds: children1 });
    }
  return result;
};
const changeFieldsTreeFromBack = async (original:any)=>{
  // console.log(original)
  try {
    // table.tableLoading.value = true;
    const data: Response = await post({
      url: changeFieldsTree,
      data:{fieldsTreeOutModels:original},
      token:userStore.getToken()
    });
  }catch(e) {
    message.error((e as Error).message)
  }finally {
    key.value = new Date().getTime()
    // table.tableLoading.value = false;
  }
}
const handleDrop = ({ node, dragNode, dropPosition }: TreeDropInfo) => {
  const data = departmentData;
  const [dragNodeSiblings, dragNodeIndex] = findSiblingsAndIndex(dragNode, data.value);
  console.log('dragNodeSiblings',dragNodeSiblings,dragNodeIndex,dropPosition);
  if (dragNodeSiblings === null || dragNodeIndex === null) return;
  dragNodeSiblings.splice(dragNodeIndex, 1);
  if (dropPosition === "inside") {
    // console.log("inside");
    if (node.children) {
      node.children.unshift(dragNode);
    } else {
      node.children = [dragNode];
    }
  } else if (dropPosition === "before") {
    const [nodeSiblings, nodeIndex] = findSiblingsAndIndex(node, data.value);
    if (nodeSiblings === null || nodeIndex === null) return;
    nodeSiblings.splice(nodeIndex, 0, dragNode);
  } else if (dropPosition === "after") {
    const [nodeSiblings, nodeIndex] = findSiblingsAndIndex(node, data.value);
    if (nodeSiblings === null || nodeIndex === null) return;
    nodeSiblings.splice(nodeIndex + 1, 0, dragNode);
  }
  const original = getOrignalData(data.value);
  changeFieldsTreeFromBack(original)
};

// 展开
const expandAllFlag = ref(false)
const getExpandedKeys = shallowReactive(useSurfaceSetting.getSurfaceSetting().fieldExpandKeys as Array<number>)
function onUpdateExpandedKeys(keys: any) {
  getExpandedKeys.length = 0
  getExpandedKeys.push(...keys)
  // console.log(getExpandedKeys)
}
watch(() => expandAllFlag.value,
    (newVal) => {newVal
        ? getExpandedKeys.push(...departmentData.value.map((it) => it.key))
        : (getExpandedKeys.length = 0)
    }
)
watch(getExpandedKeys, ()=>{
  useSurfaceSetting.getSurfaceSetting().fieldExpandKeys = [...getExpandedKeys.values()]
})

</script>
<style lang="scss" scoped>
.avatar-container {
  position: relative;
  width: 30px;
  margin: 0 auto;
  vertical-align: middle;
  .avatar {
    width: 100%;
    border-radius: 50%;
  }
  .avatar-vip {
    border: 2px solid #cece1e;
  }
  .vip {
    position: absolute;
    top: 0;
    right: -9px;
    width: 15px;
    transform: rotate(60deg);
  }
}
.gender-container {
  .gender-icon {
    width: 20px;
  }
}
</style>